//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using OpenLS.Core.Serialization;

namespace OpenLS.Chart
{
    ///<summary>
    /// Represents a 2D bar chart.
    ///</summary>
    public class BarChart : BarChartBase
    {
        private int _gapWidth = 150;
        private int _overlap;
        private List<ChartLines> _chartLines;
        private Axis _secondAxis;


        /// <summary>
        /// Initialized a new 2D bar chart.
        /// </summary>
        public BarChart()
        {
            FirstAxis = new CategoryAxis {Position = AxisPosition.Bottom};
            SecondAxis = new ValueAxis {Position = AxisPosition.Left};
            FirstAxis.CrossAxis = SecondAxis;
            SecondAxis.CrossAxis = FirstAxis;
        }
        internal override void OnDirectionChanged(BarDirection direction)
        {
            Axis valueAxis = ValueAxis;
            Axis categoryAxis = CategoryAxis;
            if (direction == BarDirection.Bar)
            {
                switch (valueAxis.Position)
                {
                    case AxisPosition.Left:
                    case AxisPosition.Right:
                        valueAxis.Position = AxisPosition.Bottom;
                        break;
                }
                switch (categoryAxis.Position)
                {
                    case AxisPosition.Bottom:
                        case AxisPosition.Top:
                        categoryAxis.Position = AxisPosition.Left;
                        break;
                }
            }
            else
            {
                switch (valueAxis.Position)
                {
                    case AxisPosition.Top:
                    case AxisPosition.Bottom:
                        valueAxis.Position = AxisPosition.Left;
                        break;
                }
                switch (categoryAxis.Position)
                {
                    case AxisPosition.Left:
                    case AxisPosition.Right:
                        categoryAxis.Position = AxisPosition.Bottom;
                        break;
                }
            }

        }

        public IEnumerable<NumericValue> Values
        {
            get
            {
                foreach (BarSeries s in Series)
                {
                    foreach (NumericValue v in s.Values.NumericValues)
                        yield return v;
                }
            }
        }


        public int GapWidth
        {
            get { return _gapWidth; }
            set
            {
                _gapWidth = value;
                notifyPropertyChanged("GapWidth");
            }
        }

        public int Overlap
        {
            get { return _overlap; }
            set
            {
                _overlap = value;
                notifyPropertyChanged("Overlap");
            }
        }

        public List<ChartLines> ChartLines
        {
            get
            {
                if (_chartLines == null)
                    _chartLines = new List<ChartLines>();
                return _chartLines;
            }
        }

        public ValueAxis ValueAxis
        {
            get
            {
                var a = FirstAxis as ValueAxis;
                if (a != null)
                    return a;
                return _secondAxis as ValueAxis;
            }
        }

        public Axis CategoryAxis
        {
            get
            {
                var a = FirstAxis as ValueAxis;
                if (a != null)
                    return _secondAxis;
                return FirstAxis;
            }
        }


        private Axis FirstAxis { get; set; }

        Axis SecondAxis
        {
            get { return _secondAxis; }
            set
            {
                _secondAxis = value;
            }
        }

        internal override void WriteXmlCore(WriteContext context)
        {
            using (WriteContext c = context.Write("barChart"))
            {
                //\\c.PassAttributes();
                WriteXmlBase(c);
                c.WriteOptionalElementIntegerAttribute("gapWidth", "val", GapWidth, 150);
                c.WriteOptionalElementIntegerAttribute("overlap", "val", Overlap, 0);
                foreach (ChartLines l in ChartLines)
                    c.WriteElementAs(l, "serLines");
                c.WriteOptionalElementUIntegerAttribute("axId", "val", FirstAxis.Id, 0);
                c.WriteOptionalElementUIntegerAttribute("axId", "val", SecondAxis.Id, 0);
                c.WarnIf("crtExt");
            }
        }

        protected override void VerifyAxes()
        {
            ValueAxis.CrossAxis = CategoryAxis;
            CategoryAxis.CrossAxis = ValueAxis;
        }

        internal override void ReadXmlCore(ReadContext context)
        {
            using (var c = context.Read("barChart"))
            {
                c.PassAttributes();
                ReadXmlBase(c);
                GapWidth = c.ReadOptionalElementIntegerAttribute("gapWidth", "val", 150);
                Overlap = c.ReadOptionalElementIntegerAttribute("overlap", "val", 0);
                var s = c.ReadOptionalElementAs<ChartLines>("serLines");
                while (s != null)
                {
                    ChartLines.Add(s);
                    s = c.ReadOptionalElementAs<ChartLines>("serLines");
                }
                AxisResolver r = ReadContextData.GetAxisResolver(c);
                r.AddAction(c.ReadElementUIntegerAttribute("axId"), delegate(Axis a) { FirstAxis = a; });
                r.AddAction(c.ReadElementUIntegerAttribute("axId"), delegate(Axis a) { SecondAxis = a; });
                c.WarnIf("crtExt");
            }
        }

        public IEnumerable<NumericValue> GetValues()
        {
            foreach (BarSeries s in Series)
                foreach (NumericValue n in s.Values.Values)
                    yield return n;
        }


        internal override IEnumerable<Axis> GetAxes()
        {
            yield return FirstAxis;
            yield return SecondAxis;
        }
    }
}